package com.hxgis.oc.cma;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.hxgis.oc.cma.util.CmaElementRequest;
import com.hxgis.oc.cma.util.CmaUrlGenerator;
import com.hxgis.oc.config.OConfig;
import com.hxgis.oc.util.geotools.GeoConvertor;
import com.hxgis.oc.util.idw.IDWConvertor;
import lombok.extern.slf4j.Slf4j;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;

import java.io.File;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class SurfEleRequest extends CmaElementRequest {
    public static final String dataCode = "SURF_CHN_MUL_HOR";
    private static final String interfaceId = "getSurfEleByTime";
    private static final String elements = "Province,Station_Name,Datetime,TEM,Lon,Lat,PRE_1h";

    @Override
    public String getDataTable() {
        return "SurfEle";
    }

    @Override
    public String generateQueryUrl(LocalDateTime time) {
        Map<String, Object> requestParams = new HashMap<>();
        requestParams.put("dataCode",dataCode);
        requestParams.put("times", OConfig.formatQueryString(time));
        requestParams.put("elements",elements);
        return CmaUrlGenerator.generateJsonUrl(requestParams,interfaceId);
    }

    public static IDWConvertor createIDWProduct(File jsonFile) {
        GeoConvertor geoConvertor = jsonToShp(jsonFile);
        if(geoConvertor == null){
            return null;
        }
        IDWConvertor idwConvertor = new IDWConvertor();
        try{
            idwConvertor.setIncreaseValue(20.0f);
            idwConvertor.setMultiply_value(3.64285714f);
            idwConvertor.setGeoConvertor(geoConvertor);
            idwConvertor.setContourDis(5);
            idwConvertor.setFiledName("TEM");
            idwConvertor.setWidth(1024);
            idwConvertor.setHeight(1024);
        }catch (Exception e){
            log.error(e.getMessage());
        }

        return idwConvertor;
    }

    public static GeoConvertor jsonToShp(File file) {
        GeoConvertor oper = new GeoConvertor();

        SimpleFeatureTypeBuilder builder = oper.createPointTypeBuilder();
        builder.add("Province", String.class);
        builder.add("Station", String.class);
        builder.add("TEM", Float.class);

        try {
            JSONObject jsonObject = JSONUtil.readJSONObject(file, Charset.forName("UTF-8"));
            int returnCode = jsonObject.getInt("returnCode");
            if (returnCode == 0) {
                List<JSONObject> ds = jsonObject.getJSONArray("DS").toList(JSONObject.class);
                for(JSONObject t : ds){
                    float longitude = t.getFloat("Lon");
                    float latitude = t.getFloat("Lat");
                    if(longitude < 70.0 || longitude > 140.0
                            ||latitude < 17.0 || latitude > 55.0){
                        continue;
                    }

                    String pro = t.getStr("Province");
                    String sta = t.getStr("Station_Name");
                    float tem = t.getFloat("TEM");
                    if(tem > 999.0 || tem < -50.0 || tem == 0.0){
                        continue;
                    }
                    oper.addPoint(longitude,latitude,new Object[]{
                            new String(pro.getBytes(StandardCharsets.UTF_8),"UTF-8"),
                            new String(sta.getBytes(StandardCharsets.UTF_8),"UTF-8"),
                            tem
                    });
                }

            }
        }catch (Exception e){
            log.error(e.getMessage());
        }

        return oper;
    }

    public static IDWConvertor createIDWProduct2(File jsonFile) {
        GeoConvertor geoConvertor = jsonToShp2(jsonFile);
        if(geoConvertor == null){
            return null;
        }
        IDWConvertor idwConvertor = new IDWConvertor();
        try{
            idwConvertor.setNodataValue(-20.0f);
            idwConvertor.setGeoConvertor(geoConvertor);
            idwConvertor.setFiledName("PRE_1h");
            idwConvertor.setWidth(1024);
            idwConvertor.setHeight(1024);
        }catch (Exception e){
            log.error(e.getMessage());
        }

        return idwConvertor;
    }

    public static GeoConvertor jsonToShp2(File file) {
        GeoConvertor oper = new GeoConvertor();

        SimpleFeatureTypeBuilder builder = oper.createPointTypeBuilder();
        builder.add("Province", String.class);
        builder.add("Station", String.class);
        builder.add("PRE_1h", Float.class);

        try {
            JSONObject jsonObject = JSONUtil.readJSONObject(file, Charset.forName("UTF-8"));
            int returnCode = jsonObject.getInt("returnCode");
            if (returnCode == 0) {
                List<JSONObject> ds = jsonObject.getJSONArray("DS").toList(JSONObject.class);
                for(JSONObject t : ds){
                    float longitude = t.getFloat("Lon");
                    float latitude = t.getFloat("Lat");
                    if(longitude < 70.0 || longitude > 140.0
                            ||latitude < 17.0 || latitude > 55.0){
                        continue;
                    }

                    String pro = t.getStr("Province");
                    String sta = t.getStr("Station_Name");
                    float value = t.getFloat("PRE_1h");
                    if(value > 9999.0 || value < 0.0){
                        continue;
                    }
                    oper.addPoint(longitude,latitude,new Object[]{
                            new String(pro.getBytes(StandardCharsets.UTF_8),"UTF-8"),
                            new String(sta.getBytes(StandardCharsets.UTF_8),"UTF-8"),
                            value
                    });
                }

            }
        }catch (Exception e){
            log.error(e.getMessage());
        }

        return oper;
    }

    public static JSONObject createGeojsonProduct(File file){
        JSONObject ret = null;
        try{
            JSONObject jsonObject = JSONUtil.readJSONObject(file, Charset.forName("UTF-8"));
            int returnCode = jsonObject.getInt("returnCode");
            if(returnCode == 0){
                List<JSONObject> ds = jsonObject.getJSONArray("DS").toList(JSONObject.class);
                JSONObject geoJson = new JSONObject();
                geoJson.set("type","FeatureCollection");
                List<JSONObject> features = new ArrayList<>();
                for(JSONObject t : ds){
                    float longitude = t.getFloat("Lon");
                    float latitude = t.getFloat("Lat");
                    if(longitude < 70.0 || longitude > 140.0
                        ||latitude < 17.0 || latitude > 55.0){
                        continue;
                    }

                    JSONObject feature = new JSONObject();
                    feature.set("type","Feature");
                    JSONObject geometry = new JSONObject();
                    geometry.set("type","Point");
                    geometry.set("coordinates",new Float[]{t.getFloat("Lon"),t.getFloat("Lat")});
                    feature.set("geometry",geometry);
                    JSONObject properties = new JSONObject();
                    properties.set("Station_Name",t.getStr("Station_Name"));
                    properties.set("Province",t.getStr("Province"));
                    properties.set("TEM",t.getFloat("TEM"));
                    properties.set("PRE_1h",t.getFloat("PRE_1h"));
                    feature.set("properties",properties);

                    features.add(feature);
                }

                geoJson.set("features",features);
                if(features.size() > 0){
                    ret = geoJson;
                }
            }
        }catch(Exception e){
            log.error(e.getMessage());
        }

        return ret;
    }
}
